﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Text;

namespace GeneralDashboard.Data.Core
{
    public class AsciiSplitProtocol : ProtocolBase
    {
        public char FrameSplitor { get; }
        public char DataSplitor { get; }

        private bool _initialized;
        private AsciiSplitReaderStatus _status;

        private Stream _baseStream;
        private List<byte> _readBuffer;

        public AsciiSplitProtocol(IDictionary<string, Type> frameSequence, char frameSplitor, char dataSplitor)
            : base(frameSequence)
        {
            FrameSplitor = frameSplitor;
            DataSplitor = dataSplitor;
            _initialized = false;
        }

        public bool Initialise(Stream stream)
        {
            if (stream == null || !stream.CanRead)
                return false;
            _status = AsciiSplitReaderStatus.WaitingForHead;
            _baseStream = stream;
            _readBuffer = new List<byte>(512);

            _initialized = true;
            return _initialized;
        }

        public override void GetFrameData()
        {
            if (_status == AsciiSplitReaderStatus.FrameFinish)
            {
                _readBuffer.Clear();
                _status = AsciiSplitReaderStatus.InFrame;
            }
            while (_status == AsciiSplitReaderStatus.WaitingForHead)
            {
                int currentByte;
                if ((currentByte = _baseStream.ReadByte()) == -1) continue;
                if((char)currentByte == FrameSplitor)
                {
                    _status = AsciiSplitReaderStatus.InFrame;
                    break;
                }
            }
            while(_status == AsciiSplitReaderStatus.InFrame)
            {
                int currentByte;
                if ((currentByte = _baseStream.ReadByte()) == -1) continue;
                if ((char)currentByte == FrameSplitor)
                {
                    _status = AsciiSplitReaderStatus.FrameFinish;
                    break;
                }
                _readBuffer.Add((byte)currentByte);
            }
            if (_status == AsciiSplitReaderStatus.FrameFinish)
            {
                var strDataArray = Encoding.ASCII.GetString(_readBuffer.ToArray()).Split(DataSplitor);
                if (strDataArray.Length != _frameSequence.Count)
                {
                    // TODO 处理错误的数据帧
                }
                int index = 0;
                foreach(var item in _dataDict)
                {
                    item.Value.SetValue(strDataArray[index++]);
                }
            }
            base.GetFrameData();
        }
    }

    enum AsciiSplitReaderStatus
    {
        WaitingForHead,
        InFrame,
        FrameFinish
    }
}
